#include <iostream>
#include <cstdio>
#include <cassert>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <string>
#include <cstring>

using namespace std;

int main() 
{
    int fds[2];
    int n = pipe(fds);
    assert(n == 0);

    pid_t id = fork();
    
    if (id == 0) 
    { 
        // 子进程
        close(fds[0]); // 关闭读取端
        
        const char* s = "I am the child process";
        int cnt = 0;
        while (true) 
        { 
            cnt++;
            char buffer[1024];
            //将格式化的字符串写入buffer
            snprintf(buffer, sizeof(buffer), "child->parent say: %s[%d][%d]\n", s, cnt, getpid());
            //写入端写满后 再写入会阻塞 等待读取端读取后再写入
            //将buffer内有效内容写入管道写端
            write(fds[1], buffer, strlen(buffer));
            //sizeof(buffer)：返回 buffer 的 总大小（比如 char buffer[1024] 就是 1024）
            //strlen(buffer)：返回 buffer 中 已存储的字符串的长度（直到 \0）
            sleep(1);
        }
        
        close(fds[1]); // 关闭写入端
        exit(0);
    } 
    else 
    { 
        // 父进程
        close(fds[1]); // 关闭写入端
        
        while (true) 
        {
            char buffer[1024];
            //如果管道中没有数据 读取端正在读取 默认会直接阻塞当前读取进程
            ssize_t s = read(fds[0], buffer, sizeof(buffer)-1);
            if (s > 0) 
            {
                buffer[s] = 0;
                cout << "Get Message#" << buffer << "| My PID:" << getpid() << endl;
            } 
            else if (s == 0) 
            { 
                // 子进程关闭了写入端
                // 读到文件结尾
                cout << "Child process closed the pipe" << endl;
                break;
            } 
            else 
            {
                perror("read");
                break;
            }
        }
        
        close(fds[0]); // 父进程关闭读取端
        int status=0;
        n=waitpid(id, &status, 0); // 等待子进程结束
        cout<<n<<": "<<(status & 0x7F)<<endl;
    }



    return 0;
}